package dom.xpath.query.xpath.expr;

import dom.xpath.query.EvalException;
import dom.xpath.query.xpath.XPContext;
import dom.xpath.query.xpath.values.NodeSet;
import dom.xpath.query.xpath.values.Item;

/**
 * Path Expression.
 * This Expression represents a relative location path operating
 * on a nodeset (return value of expression).
 * 
 * @author Workgroup DBIS, University of Konstanz 2005-07, ISC License
 * @author Tim Petrowsky
 */
public final class Path extends Expression {
  /** Expression to be evaluated. */
  public Expression expr;
  /** Location path. */
  public Expression path;

  /**
   * Constructor for a relative location path.
   * @param e Expression evaluating to a nodeset
   * @param p Location Path (or maybe other Expression after optimization)
   */
  public Path(final Expression e, final Expression p) {
    expr = e;
    path = p;
  }

  @Override
  public NodeSet eval(final XPContext ctx) throws EvalException {
    final Item val = ctx.eval(expr);
    if(val instanceof NodeSet) ctx.local = (NodeSet) val;
    ctx.local = (NodeSet) ctx.eval(path);
    return ctx.local;
  }

  @Override
  public boolean usesSize() {
    return expr.usesSize() || path.usesSize();
  }
  
  @Override
  public boolean usesPos() {
    return expr.usesPos() || path.usesPos();
  }

  @Override
  public Expression compile(final XPContext ctx) throws EvalException {
    expr = expr.compile(ctx);
    path = path.compile(ctx);
    return this;
  }

  @Override
  public String toString() {
    return "Path(" + expr + ", " + path + ')';
  }
}
